package persistencia.carreras;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Observable;


import modelo.escenario.Cruce;
import modelo.carrera.Carrera;
import modelo.carrera.ObservadorDeCarrera;
import modelo.comportamiento.acciones.Acelerar;
import modelo.controles.Control;
import modelo.escenario.Cuadra;
import modelo.geometria.Circunferencia;
import modelo.geometria.Figura;
import modelo.geometria.Rectangulo;
import modelo.geometria.Vector;
import modelo.obstaculos.Obstaculo;
import modelo.seniales.ISenial;
import modelo.seniales.Semaforo;
import modelo.seniales.carteles.Cartel;
import modelo.vehiculos.Vehiculo;

public class ObservadorDeCarreraSVG extends ObservadorDeCarrera {
	protected File directorio;
	
	public ObservadorDeCarreraSVG(String directorio) {
		File dir = new File(directorio);
		if (dir.isDirectory())
			this.directorio = dir;
		else
			this.directorio = new File(".");
	}

	public File getDirectorio() {
		return directorio;
	}
	
	protected static String Encabezado(double centroX, double centroY) {
		String encabezado = "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">";
		encabezado+= "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width='1000px' height='618px'>";
		encabezado+= "<g transform=\""+
						"translate("+String.valueOf(centroX)+","+String.valueOf(centroY)+")" +
						" scale(10, 10)\">";

		return encabezado;
	}
	
	protected static String Pie() {
		return "</g></svg>";
	}
	
	protected String imprimirRectangulo(double centroX, double centroY, double largo, double ancho, String colorFondo, String colorBorde, double opaco) {
		Double x = centroX-ancho/2;
		Double y = centroY-largo/2;
		String rectangulo = 
			"<rect" +
			" x=\"" + x.toString() + "\"" +
			" y=\"" + y.toString() + "\"" +
			" width=\"" + String.valueOf(ancho) + "\"" +
			" height=\"" + String.valueOf(largo) + "\"" +
			" style=\"fill:" + colorFondo + ";stroke:" + colorBorde + "\"" +
			" opacity=\"" + String.valueOf(opaco) + "\"" +
			"/>";
		return rectangulo;
	}
	
	protected String imprimirCirculo(double centroX, double centroY, double radio, String colorFondo, String colorBorde, double opaco) {
		Double x = centroX;
		Double y = centroY;
		String circulo =
			"<circle" +
			" cx=\"" + x.toString() + "\"" +
			" cy=\"" + y.toString() + "\"" +
			" r=\"" + String.valueOf(radio) + "\"" +
			" style=\"fill:" + colorFondo + ";stroke:" + colorBorde + "\"" +
			" opacity=\"" + String.valueOf(opaco) + "\"" +
		    "/>";
		
		return circulo;
	}
	
	protected String imprimirFigura(Figura figura, String colorFondo, String colorBorde, double opaco) {
		if (figura instanceof Circunferencia) {
			Circunferencia c = (Circunferencia)figura;
			return imprimirCirculo(c.getCentro().getX(),
								   c.getCentro().getY(),
								   c.getRadio(),
								   colorFondo, colorBorde, opaco);
		}
		if (figura instanceof Rectangulo) {
			Rectangulo r = (Rectangulo)figura;
			return imprimirRectangulo(	r.getCentro().getX(),
										r.getCentro().getY(),
										r.getLargo(),
										r.getAncho(),
										colorFondo, colorBorde, opaco);
		}
			
		return "<figura clase=\""+ figura.getClass().getSimpleName() + "\"/>";
	}
	
	protected String getColorDeFondo(Obstaculo obstaculo) {
		if (obstaculo instanceof Semaforo)
			return "yellow";
		if (obstaculo instanceof Control)
			return "blue";
		if (obstaculo instanceof Cartel)
			return "violet";
		if (obstaculo instanceof ISenial)
			return "cyan";
		if (obstaculo instanceof Vehiculo)
			return "tomato";
		
		return "black";
	}
	
	protected String getColorDeBorde(Obstaculo obstaculo) {
		if (obstaculo instanceof Control)
			return "white";
		if (obstaculo instanceof Vehiculo)
			return "red";
		
		return "black";
	}
	
	protected String imprimirTexto(Vector posicion, String texto) {
		String impresion = "";
		//String impresion+= "<g transform=\"scale(1,-1)\">";
		impresion+= "<text font-family=\"Verdana\" font-size=\"3\" fill=\"blue\" "+
							"x=\""+ posicion.getX() + "\" y=\""+ posicion.getY() +"\">"+texto+"</text>";
		//impresion+="</g>";
		return impresion;
	}
	
	protected void armarArchivo(Carrera carrera, long instante) {
		File foto = new File(directorio.getAbsoluteFile() + directorio.separator + String.valueOf(instante)+ ".svg");
		PrintStream impresora = null;
		try {
			foto.createNewFile();
			impresora = new PrintStream(foto);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// impresora.println(Encabezado(250,618-(314/2))); //<< para el rotado
		impresora.println(Encabezado(250,618/4));
		
		//Dibujo el mapa 1000x618.
		impresora.println(imprimirRectangulo(0, 0, 1000, 1000, "forestgreen", "black", 1.0));
		
		for (Cuadra cuadra : carrera.getEscenario().getGuiaT().obtenerCuadras()) {
			String figura = imprimirFigura(cuadra.getSuperficie(), "slategrey", "white",1.0);
			impresora.println(figura);
		}
		
		for (Cruce cruce : carrera.getEscenario().getGuiaT().obtenerCruces()) {
			String figura = imprimirFigura(cruce.getSuperficie(),"darkslategrey","white",1.0);
			impresora.println(figura);
		}
		
		for (Obstaculo obstaculo : carrera.getEscenario().getObstaculos()) {
			String figura = imprimirFigura(obstaculo.getCuerpo(),
						   getColorDeFondo(obstaculo), getColorDeBorde(obstaculo), 0.5);
			impresora.println(figura);
			impresora.println(imprimirTexto(obstaculo.getPosicion(), obstaculo.getClass().getSimpleName().substring(0,1)));
		}
		
		for (Control control : carrera.getEscenario().getControles()) {
			String figura = imprimirFigura(	control.getVision(), "white", "black", 0.5);
			impresora.println(figura);
		}
		
		impresora.println(Pie());
		
		impresora.flush();
		impresora.close();
}
	
	@Override
	protected void armarMapa(Carrera carrera) {
		armarArchivo(carrera, 0);
	}

	@Override
	protected void armarTick(Carrera carrera, long instante) {
		armarArchivo(carrera, getInstante());
	}	
}
